home *** CD-ROM | disk | FTP | other *** search
/ The Very Best of Atari Inside / The Very Best of Atari Inside 1.iso / mint / mntlib43 / mntlib / a64l.c < prev    next >
C/C++ Source or Header  |  1993-07-06  |  4KB  |  163 lines

  1. /****************************************************************/
  2. /* Module name:   a64l.c                                        */
  3. /* Library name:  mintlibs for Atari ST                         */
  4. /* Author:        Hildo Biersma (boender@dutiws.twi.tudelft.nl) */
  5. /* Date:          January 11, 1993                              */
  6. /* Revision:      1 (first attempt)                             */
  7. /*                2 ++entropy Made compatible with K&R compilers*/
  8. /****************************************************************/
  9.  
  10. /* FIXME: maybe use ERANGE or EDOM instead of EBADARG */
  11.  
  12. /*
  13. NAME
  14.     a64l, l64a - convert between long integer and base-64 ASCII string
  15.  
  16. SYNOPSIS
  17.     #include <support.h>
  18.     long a64l(const char *s);
  19.     char *l64a(long l);
  20.  
  21. DESCRIPTION
  22.     These functions are used to maintain numbers stored in base-64
  23.     ASCII characters. This is a notation by which long integers
  24.     can be represented by up to six characters; each character
  25.     represents a "digit" in a radix-64 notation.
  26.     
  27.     The characters used to represent "digits" are . for 0, / for 1,
  28.     0 through 9 for 2-11, A through Z for 12-37, and a through z
  29.     for 38-63.
  30.     
  31.     a64l takes a pointer to a null-terminated base-64 representation
  32.     and returns a corresponding long value. If the string pointed to
  33.     by s contains more than six characters, a64l will use the first
  34.     six. a64l scans the character string from left to right, decoding
  35.     each character as a 6 bit radix-64 number. If the string contains
  36.     illegal characters, -1 is returned and errno is set to EBADARG.
  37.     
  38.     l64a takes a long argument and returns a pointer to the
  39.     corresponding base-64 representation. If the argument is 0, a64l
  40.     returns a pointer to a null string. If the argument is smaller
  41.     than zero, a pointer to a null string is returned and errno is
  42.     set to EBADARG.
  43.  
  44. CAVEATS
  45.     The value returned by l64a is a pointer into a static buffer,
  46.     the contents of which are overwritten by each call.
  47.     
  48.     The value returned by a64l may be incorrect if the value
  49.     is too large; for that reason, only strings that resulted
  50.     from a call to l64a should be used to call a64l.
  51.  
  52.     Maybe these calls should unsigned long values, but longs are
  53.     used here to retain compatibility with UN*X System V.
  54.  
  55. AUTHOR
  56.     Hildo Biersma, with the help of a UN*X System V man page.
  57. */
  58.  
  59. #include <support.h>
  60. #include <errno.h>
  61. extern int errno;
  62.  
  63. #ifndef _COMPILER_H
  64. #include <compiler.h>
  65. #endif
  66.  
  67. /* Local function prototypes */
  68. static int a64i __PROTO((char c));  /* base-64 char to int, -1 on error */
  69. static char i64a __PROTO((int i));  /* integer to base-64 char, 0x7F on error */
  70.  
  71. /* base-64 char to int, -1 on error */
  72. static int a64i(c)
  73.   char c;
  74. {
  75.   int retval = c;
  76.  
  77.   if ((c < '.') || (c > 'z'))
  78.   {
  79.     errno = EBADARG;
  80.     return(-1);
  81.   }
  82.   retval -= '.';
  83.   if (c > '9')
  84.     retval -= 'A' - '9' - 1;
  85.   if (c > 'Z')
  86.     retval -= 'a' - 'Z' - 1;
  87.   if (retval > 63)
  88.   {
  89.     errno = EBADARG;
  90.     return(-1);
  91.   }
  92.   return(retval);
  93. } /* End of a64i() */
  94.  
  95. /* base-64 string to long */
  96. long a64l(s)
  97.   const char *s;
  98. {
  99.   long retval = 0;
  100.   int counter = 0;
  101.   const char *ptr = s;
  102.  
  103.   while ((counter++ < 6) && (*ptr != 0x00))
  104.   {
  105.     int val;
  106.     
  107.     if ((val = a64i(*ptr++)) == -1)
  108.       return(-1); /* errno was set by a64i() */
  109.     retval <<= 6;
  110.     retval += val;
  111.   }
  112.   return(retval);
  113. } /* End of a64l() */
  114.  
  115. /* integer to base-64 char, 0x7F on error */
  116. static char i64a(i)
  117.   int i;
  118. {
  119.   char retval = (char)i;
  120.   
  121.   if ((i < 0) || (i > 63))
  122.   {
  123.     errno = EBADARG;
  124.     return(0x7F);
  125.   }
  126.   retval += '.';
  127.   if (i > 11)
  128.     retval += 'A' - '9' - 1;
  129.   if (i > 37)
  130.     retval += 'a' - 'Z' - 1;
  131.   return(retval);
  132. } /* End of i64a() */
  133.  
  134. /* long to base-64 string */
  135. char *l64a(l)
  136.   long l;
  137. {
  138.   static char retval[7];
  139.   char buffer[7], *ptr1 = buffer, *ptr2 = retval;
  140.   int counter = 0;
  141.  
  142.   if (l < 0)
  143.   {
  144.     errno = EBADARG;
  145.     return("");
  146.   }
  147.   if (l == 0)
  148.     return("");
  149.   while ((counter++ < 6) && (l > 0))
  150.   {
  151.     char val;
  152.     
  153.     if ((val = i64a((char)(l & 0x3F))) == 0x7F)
  154.       return(""); /* errno was set by i64a() */
  155.     *ptr1++ = val;
  156.     l >>= 6;
  157.   }
  158.   while (ptr1 > buffer)
  159.     *ptr2++ = *(--ptr1);
  160.   *ptr2 = 0x00;
  161.   return(retval);
  162. } /* End of l64a() */
  163.